package cn.harry.cabinet.utils

import android.util.Log

/**
 * 卡片数据解析器
 * 支持多种刷卡器数据格式的解析
 */
object CardDataParser {

    private const val TAG = "CardDataParser"

    /**
     * 卡片解析结果
     */
    data class CardParseResult(
        val success: Boolean,
        val cardId: String,
        val cardType: String = "UNKNOWN",
        val rawData: String,
        val parseMethod: String
    )

    /**
     * 解析卡片数据
     * @param buffer 原始数据缓冲区
     * @param size 数据大小
     * @return 解析结果
     */
    fun parseCardData(buffer: ByteArray, size: Int): CardParseResult {
        val hexString = buffer.take(size).joinToString("") {
            String.format("%02X", it)
        }

        Log.d(TAG, "开始解析卡片数据 (${size}字节): $hexString")

        // 尝试多种解析方法
        val results = mutableListOf<CardParseResult>()

        // 方法1: 解析特定格式 (02 30 31 38 31 30 31 44 34 0D 0A 03)
        parseSpecificFormat(buffer, size, hexString)?.let { results.add(it) }

        // 方法2: ASCII码格式解析
        parseAsciiFormat(buffer, size, hexString)?.let { results.add(it) }

        // 方法3: 标准十六进制格式
        parseHexFormat(buffer, size, hexString)?.let { results.add(it) }

        // 方法4: Wiegand格式解析
        parseWiegandFormat(buffer, size, hexString)?.let { results.add(it) }

        // 返回最可能的结果
        return results.firstOrNull { it.success } ?: CardParseResult(
            success = false,
            cardId = "",
            rawData = hexString,
            parseMethod = "FAILED"
        )
    }

    /**
     * 解析特定格式: 02 30 31 38 31 30 31 44 34 0D 0A 03
     * 其中：30 31 38 31 30 31 44 34 为卡号的四个字节的ASCII码
     */
    private fun parseSpecificFormat(
        buffer: ByteArray,
        size: Int,
        hexString: String
    ): CardParseResult? {
        return try {
            // 检查格式：以02开头，0D 0A 03结尾
            if (size >= 12 &&
                buffer[0] == 0x02.toByte() &&
                buffer[size - 3] == 0x0D.toByte() &&
                buffer[size - 2] == 0x0A.toByte() &&
                buffer[size - 1] == 0x03.toByte()
            ) {

                // 提取中间的ASCII码部分
                val asciiHexPart = buildString {
                    for (i in 1 until size - 3) {
                        append(buffer[i].toChar())
                    }
                }

                Log.d(TAG, "特定格式ASCII码部分: $asciiHexPart")

                // 将ASCII码转换为卡号
                val cardNumber = asciiHexToCardNumber(asciiHexPart)

                if (cardNumber.isNotEmpty()) {
                    Log.i(TAG, "特定格式解析成功，卡号: $cardNumber")
                    return CardParseResult(
                        success = true,
                        cardId = cardNumber,
                        cardType = "ASCII_HEX",
                        rawData = hexString,
                        parseMethod = "SPECIFIC_FORMAT"
                    )
                }
            }
            null
        } catch (e: Exception) {
            Log.e(TAG, "特定格式解析失败: ${e.message}")
            null
        }
    }

    /**
     * 解析ASCII码格式
     */
    fun parseAsciiFormat(
        buffer: ByteArray,
        size: Int,
        hexString: String
    ): CardParseResult? {
        return try {
            // 查找ASCII码数字部分
            val asciiPart = extractAsciiHexPart(buffer, size)
            if (asciiPart.isNotEmpty()) {
                val cardNumber = asciiHexToCardNumber(asciiPart)
                if (cardNumber.isNotEmpty()) {
                    Log.i(TAG, "ASCII格式解析成功，卡号: $cardNumber")
                    return CardParseResult(
                        success = true,
                        cardId = cardNumber,
                        cardType = "ASCII",
                        rawData = hexString,
                        parseMethod = "ASCII_FORMAT"
                    )
                }
            }
            null
        } catch (e: Exception) {
            Log.e(TAG, "ASCII格式解析失败: ${e.message}")
            null
        }
    }

    /**
     * 解析标准十六进制格式
     */
    private fun parseHexFormat(buffer: ByteArray, size: Int, hexString: String): CardParseResult? {
        return try {
            // 跳过可能的头部标识
            var startIndex = 0
            var endIndex = size

            // 检测常见的头部标识
            if (size > 2) {
                when {
                    buffer[0] == 0xAA.toByte() && buffer[1] == 0xAA.toByte() -> startIndex = 2
                    buffer[0] == 0xFF.toByte() -> startIndex = 1
                    buffer[0] == 0x02.toByte() -> startIndex = 1
                }
            }

            // 检测常见的尾部标识
            if (size > 3) {
                when {
                    buffer[size - 1] == 0x03.toByte() -> endIndex = size - 1
                    buffer[size - 2] == 0x0D.toByte() && buffer[size - 1] == 0x0A.toByte() -> endIndex =
                        size - 2
                }
            }

            if (endIndex - startIndex >= 4) { // 至少4字节的卡号数据
                val cardBytes = buffer.sliceArray(startIndex until endIndex)

                // 尝试正序
                val cardId1 = cardBytes.joinToString("") { String.format("%02X", it) }

                // 尝试逆序（小端序）
                val cardId2 =
                    cardBytes.reversedArray().joinToString("") { String.format("%02X", it) }

                // 选择更合理的卡号（通常卡号不会全是0或全是F）
                val cardId = when {
                    cardId1.all { it == '0' || it == 'F' } && !cardId2.all { it == '0' || it == 'F' } -> cardId2
                    !cardId1.all { it == '0' || it == 'F' } -> cardId1
                    else -> cardId2
                }

                Log.i(TAG, "十六进制格式解析成功，卡号: $cardId")
                return CardParseResult(
                    success = true,
                    cardId = cardId,
                    cardType = "HEX",
                    rawData = hexString,
                    parseMethod = "HEX_FORMAT"
                )
            }
            null
        } catch (e: Exception) {
            Log.e(TAG, "十六进制格式解析失败: ${e.message}")
            null
        }
    }

    /**
     * 解析Wiegand格式
     */
    private fun parseWiegandFormat(
        buffer: ByteArray,
        size: Int,
        hexString: String
    ): CardParseResult? {
        return try {
            if (size >= 4) {
                // Wiegand 26位格式：通常是4字节数据
                val wiegandData = buffer.take(4).toByteArray()
                val cardNumber = wiegandData.fold(0L) { acc, byte ->
                    (acc shl 8) + (byte.toInt() and 0xFF)
                }

                if (cardNumber > 0) {
                    Log.i(TAG, "Wiegand格式解析成功，卡号: $cardNumber")
                    return CardParseResult(
                        success = true,
                        cardId = cardNumber.toString(),
                        cardType = "WIEGAND",
                        rawData = hexString,
                        parseMethod = "WIEGAND_FORMAT"
                    )
                }
            }
            null
        } catch (e: Exception) {
            Log.e(TAG, "Wiegand格式解析失败: ${e.message}")
            null
        }
    }

    /**
     * 提取ASCII码十六进制部分
     */
    private fun extractAsciiHexPart(buffer: ByteArray, size: Int): String {
        val asciiPart = StringBuilder()

        for (i in 0 until size) {
            val byte = buffer[i]
            // 检查是否为ASCII码的十六进制字符 (0-9, A-F)
            if ((byte >= 0x30 && byte <= 0x39) || // 0-9
                (byte >= 0x41 && byte <= 0x46) || // A-F
                (byte >= 0x61 && byte <= 0x66)
            ) { // a-f
                asciiPart.append(byte.toChar())
            }
        }

        return asciiPart.toString()
    }

    /**
     * 将ASCII码十六进制字符串转换为卡号
     */
    fun asciiHexToCardNumber(asciiHex: String): String {
        // 去除所有空格
        val cleanHex = asciiHex.replace(" ", "")

        // 如果长度是偶数，可能是直接的十六进制表示
        if (cleanHex.length % 2 == 0) {
            val sb = StringBuilder()
            var i = 0
            while (i < cleanHex.length) {
                val hexPair = cleanHex.substring(i, i + 2)
                // 检查是否是有效的十六进制对
                if (hexPair.all { it.isDigit() || it in 'A'..'F' || it in 'a'..'f' }) {
                    sb.append(hexPair)
                }
                i += 2
            }
            return sb.toString()
        }

        return cleanHex
    }

    /**
     * 验证卡号是否有效
     */
    fun isValidCardId(cardId: String): Boolean {
        return cardId.isNotEmpty() &&
                cardId != "0" &&
                cardId != "00000000" &&
                !cardId.all { it == '0' || it == 'F' }
    }

}